package com.diligent.cloud.sfc.factory.impl;

import com.alibaba.fastjson.JSON;
import com.canny.commons.model.Codes;
import com.canny.commons.model.ObjectResult;
import com.canny.commons.model.Result;
import com.canny.commons.page.IPage;
import com.canny.commons.page.Pagination;
import com.diligent.cloud.primary.data.feign.service.mdm.MdmMatTypeFeignService;
import com.diligent.cloud.primary.data.feign.service.rt.RtWorkCenterFeignService;
import com.diligent.cloud.primary.data.model.mdm.MdmMatType;
import com.diligent.cloud.primary.data.model.rt.RtWorkCenter;
import com.diligent.cloud.sfc.factory.StationFactory;
import com.diligent.cloud.sfc.model.MatType;
import com.diligent.cloud.sfc.model.StationType;
import com.diligent.cloud.sfc.model.info.ExtrusionInventory;
import com.diligent.cloud.sfc.service.ISfcService;
import com.diligent.cloud.sfc.util.ConverterUtil;
import com.diligent.cloud.web.model.PageAndCondition;
import com.diligent.cloud.wip.core.feign.service.WipStorageLedgerFeignService;
import com.diligent.cloud.wip.core.vo.StorageLedgerInfo;
import com.diligent.cloud.wip.panel.modle.WipStorageLedger;
import com.diligent.cloud.workorder.enums.WoOrderStatus;
import com.diligent.cloud.workorder.model.WoOrder;
import com.diligent.cloud.workorder.model.WoOrderAndMatNeedParams;
import com.diligent.cloud.workorder.model.WoOrderMatNeed;
import com.diligent.cloud.workorder.service.WoOrderFeignService;
import com.diligent.foundation.data.model.v2.Condition;
import com.google.common.base.Preconditions;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * CutStation class
 *
 * @author xf107278
 * @date 3/30/2020
 */
@Component
public class ExtrusionStation implements StationFactory {

    private WoOrderFeignService orderFeignService;
    private ISfcService sfcService;
    private WipStorageLedgerFeignService wipStorageLedgerFeignService;
    private RtWorkCenterFeignService rtWorkCenterFeignService;
    private final MdmMatTypeFeignService mdmMatTypeFeignService;


    public ExtrusionStation(WoOrderFeignService orderFeignService, ISfcService sfcService,
                            WipStorageLedgerFeignService wipStorageLedgerFeignService,
                            RtWorkCenterFeignService rtWorkCenterFeignService,
                            MdmMatTypeFeignService mdmMatTypeFeignService) {
        this.orderFeignService = orderFeignService;
        this.sfcService = sfcService;
        this.wipStorageLedgerFeignService = wipStorageLedgerFeignService;
        this.rtWorkCenterFeignService = rtWorkCenterFeignService;
        this.mdmMatTypeFeignService = mdmMatTypeFeignService;
    }


    @Override
    public Result getOrderInfo(WoOrder order) {

        ExtrusionInventory extrusionInventory = new ExtrusionInventory();

        if (!(order.getOrderType().equals(StationType.挤压工位))) {
            return ConverterUtil.ConverterByData(null, Codes.fail.getCode(), "此工单Id不处于挤压工位");
        }
        //TODO  获取机台所有工单
        //TODO  查询查询所有模具，铝棒的库存量
        //TODO  查询查询同工单噶模具，铝棒库存量
        PageAndCondition pageAndCondition = new PageAndCondition();
        Pagination pagination = new Pagination(1L, 1000000L);
        List<Condition> conditions = new ArrayList<>();
        Condition machineCodeCondition = new Condition("machineCode", "eq", order.getMachineCode(), null);
        Condition orderStatusCondition = new Condition("orderStatus", "in", WoOrderStatus.schedulings.getStatus() + "," + WoOrderStatus.inproduction.getStatus(),
                null);
        Condition systemIdCondition = new Condition("systemId", "eq", order.getSystemId(), null);
        Condition orderTypeCondition = new Condition("orderType", "eq", order.getOrderType(), null);

        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        formatter.setTimeZone(TimeZone.getTimeZone("GMT+8:00"));
        String toDay = formatter.format(order.getProduceDate());

        Condition productDateCondition = new Condition("produceDate", "eq", toDay, null);
        conditions.add(machineCodeCondition);
        conditions.add(orderStatusCondition);
        conditions.add(systemIdCondition);
        conditions.add(orderTypeCondition);
        conditions.add(productDateCondition);


        pageAndCondition.setConditions(conditions);
        pageAndCondition.setPagination(pagination);

        ResponseEntity<com.diligent.cloud.primary.data.model.Result<IPage<WoOrder>>> orderResult =
                orderFeignService.page(pageAndCondition);


        //所有进入到机台但是未开始的工单
        if (orderResult.getBody().getData().getRecords().size() != 0) {
            IPage<WoOrder> orderIPage = orderResult.getBody().getData();

            //当班模具库存量
            List<StorageLedgerInfo> mdList = new ArrayList<>();
            //相同模具库存量
            List<StorageLedgerInfo> sameMdList = new ArrayList<>();
            //当班铝棒库存量
            List<StorageLedgerInfo> asList = new ArrayList<>();
            //相同铝棒库存量
            List<StorageLedgerInfo> sameAsList = new ArrayList<>();
            Long sameAsDigit = 0L;
//            String orderMdMatCode = sfcService.getMatCodeByOrderIdAndSystemId(order.getId(),
//                    order.getSystemId(), MatType.模具);
            String orderAsMatCode = sfcService.getMatCodeByOrderIdAndSystemId(order.getId(),
                    order.getSystemId(), MatType.铝棒);

            //    Preconditions.checkNotNull(orderMdMatCode, "物料消耗表中没有此[%s]工单没有所需模具", order.getId());
            Preconditions.checkNotNull(orderAsMatCode, "物料消耗表中没有此[%s]工单没有所需铝棒", order.getId());
            //同型号铝棒
            StorageLedgerInfo storageLedgerInfo1 = newStorageLedgerInfo(order.getId(), orderAsMatCode,
                    null);
            sameAsList.add(storageLedgerInfo1);
            StorageLedgerInfo storageLedgerInfo = null;
            int i = 0;

            long time1 = System.currentTimeMillis();
            for (WoOrder woOrder : orderIPage.getRecords()) {
                if (order.getMatCode().equalsIgnoreCase(woOrder.getMatCode())) {
                    i++;
                    extrusionInventory.setUnfinishedWoOrder(i);
                } else {
                    extrusionInventory.setUnfinishedWoOrder(i);
                }
//                // 机台工单的所需模具
//                String mdMatCode = sfcService.getMatCodeByOrderIdAndSystemId(woOrder.getId(),
//                        woOrder.getSystemId(), MatType.模具);

                // 机台工单的所需铝棒
//                String asMatCode = sfcService.getMatCodeByOrderIdAndSystemId(woOrder.getId(),
//                        woOrder.getSystemId(), MatType.铝棒);

                //    Preconditions.checkNotNull(mdMatCode, "物料消耗表中没有此[%s]工单没有所需模具", woOrder.getId());
                //      Preconditions.checkNotNull(asMatCode, "物料消耗表中没有此[%s]工单没有所需模具", woOrder.getId());


//                if (orderMdMatCode.equalsIgnoreCase(mdMatCode)) {
//                    sameMdList.add(newStorageLedgerInfo(woOrder.getId(), mdMatCode, storageLedgerInfo));
//                    mdList.add(newStorageLedgerInfo(woOrder.getId(), mdMatCode, storageLedgerInfo));
//                } else {
//                    mdList.add(newStorageLedgerInfo(woOrder.getId(), mdMatCode, storageLedgerInfo));
//                }
                if (order.getCv1().equalsIgnoreCase(woOrder.getCv1())) {
                    //  if (orderAsMatCode.equalsIgnoreCase(asMatCode)) {
                    sameAsDigit++;
                    //  sameAsList.add(newStorageLedgerInfo(woOrder.getId(), asMatCode, storageLedgerInfo));
//                    asList.add(newStorageLedgerInfo(woOrder.getId(), asMatCode, storageLedgerInfo));
//                }
//                else {
//                    asList.add(newStorageLedgerInfo(woOrder.getId(), asMatCode, storageLedgerInfo));
                }
            }
            long time2 = System.currentTimeMillis();
            System.out.println("当前程序耗时：" + (time2 - time1) + "ms");
            //获取当前工单的机台环境信息

            RtWorkCenter rtWorkCenter = sfcService.getWorkCenterByCwocCode(order.getWorkCenterCode());


            //根据集合中的模具信息，查询对应的库存信息
            //TODO 目前逻辑通，待优化
//            if (mdList.size() != 0) {
//                ObjectResult<WipStorageLedger> collectLedger =
//                        wipStorageLedgerFeignService.getCollectLedger(order.getSystemId(),
//                                rtWorkCenter.getStorageCode(), new ArrayList<>(new HashSet<>(mdList)));
//
//                extrusionInventory.setOnDutyMd(String.valueOf(collectLedger.getData().getDigit().longValue() /
//                mdList.size()));
//            } else {
            extrusionInventory.setOnDutyMd("0");
//            }

//            if (asList.size() != 0) {
//                ObjectResult<WipStorageLedger> collectLedger =
//                        wipStorageLedgerFeignService.getCollectLedger(order.getSystemId(),
//                                rtWorkCenter.getStorageCode(), new ArrayList<>(new HashSet<>(asList)));
//
//                extrusionInventory.setOnDutyAs(String.valueOf(collectLedger.getData().getDigit().longValue() / asList.size()));
//            } else {
//                extrusionInventory.setOnDutyAs("-");
//            }

//            if (sameMdList.size() != 0) {
//                ObjectResult<WipStorageLedger> collectLedger =
//                        wipStorageLedgerFeignService.getCollectLedger(order.getSystemId(),
//                                rtWorkCenter.getStorageCode(), new ArrayList<>(new HashSet<>(sameMdList)));

//                extrusionInventory.setSameMd((collectLedger.getData().getDigit().longValue() / sameMdList.size()));
//            } else {
            extrusionInventory.setSameMd("0");
            //       }

            //同型号铝棒
            if (sameAsList.size() != 0) {
                ObjectResult<WipStorageLedger> collectLedger =
                        wipStorageLedgerFeignService.getCollectLedger(order.getSystemId(),
                                rtWorkCenter.getStorageCode(), new ArrayList<>(new HashSet<>(sameAsList)));
                if (sameAsDigit != 0) {
                    extrusionInventory.setSameAs(String.valueOf(collectLedger.getData().getDigit().longValue() / sameAsDigit));
                } else {
                    extrusionInventory.setSameAs(String.valueOf(0));
                }

            } else {
                extrusionInventory.setSameAs("-");
            }

            //查物料需求
            WoOrderAndMatNeedParams woOrderAndMatNeedParams = new WoOrderAndMatNeedParams();
            woOrderAndMatNeedParams.setMachCode(order.getMachineCode());
            woOrderAndMatNeedParams.setSystemId(order.getSystemId());
            woOrderAndMatNeedParams.setWoOrderStatus(order.getOrderStatus().toString());
            woOrderAndMatNeedParams.setWoOrderType(order.getOrderType().toString());
            woOrderAndMatNeedParams.setProduceDate(toDay);

            String matType = getMatType(MatType.铝棒);
            Preconditions.checkNotNull(matType, "查询不到物料代码");
            woOrderAndMatNeedParams.setMatType(matType);


            ResponseEntity<com.diligent.cloud.primary.data.model.Result> orderNedResource =
                    orderFeignService.selectWoOrderAndMatNeed(woOrderAndMatNeedParams);
            ArrayList<LinkedHashMap> orderMatNetList = (ArrayList<LinkedHashMap>) orderNedResource.getBody().getData();

            for (LinkedHashMap orderMatNetMap : orderMatNetList) {
                WoOrderMatNeed orderMatNeed = JSON.parseObject(JSON.toJSONString(orderMatNetMap), WoOrderMatNeed.class);
                storageLedgerInfo = new StorageLedgerInfo();
                storageLedgerInfo.setBatchCode(orderMatNeed.getCv1());
                storageLedgerInfo.setMatCode(orderMatNeed.getMatCode());
                asList.add(storageLedgerInfo);
            }
            ObjectResult<WipStorageLedger> collectLedger =
                    wipStorageLedgerFeignService.getCollectLedger(order.getSystemId(),
                            rtWorkCenter.getStorageCode(), new ArrayList<>(new HashSet<>(asList)));

            extrusionInventory.setOnDutyAs(String.valueOf(collectLedger.getData().getDigit().longValue() / asList.size()));

            long time3 = System.currentTimeMillis();
            System.out.println("当前程序耗时：" + (time3 - time2) + "ms");

            orderStatusCondition.setValue(WoOrderStatus.finish.getStatus());
            conditions.add(new Condition("matCode", "eq", order.getMatCode(), null));
            pageAndCondition.setConditions(conditions);
            orderResult =
                    orderFeignService.page(pageAndCondition);
            //已完成工单
            if (orderResult.getBody().getData().getRecords().size() != 0) {
                orderIPage = orderResult.getBody().getData();
                extrusionInventory.setOrderCompleted(orderIPage.getRecords().size());
            } else {
                extrusionInventory.setOrderCompleted(0);
            }

            return ConverterUtil.ConverterByData(extrusionInventory, Codes.success.getCode(),
                    Codes.success.getMsg());


        } else {
            return ConverterUtil.ConverterByData(null, Codes.success.getCode(),
                    "无未开始工单");
        }
    }


    private StorageLedgerInfo newStorageLedgerInfo(Long orderId, String matCode, StorageLedgerInfo storageLedgerInfo) {
        storageLedgerInfo = new StorageLedgerInfo();
        storageLedgerInfo.setMatCode(matCode);
        storageLedgerInfo.setBatchCode(sfcService.getBatchCodeByOrderId(orderId, storageLedgerInfo.getMatCode()));
        return storageLedgerInfo;
    }

    private String getMatType(String type) {
        ResponseEntity<com.diligent.cloud.primary.data.model.Result> mdmMatTypeResult =
                mdmMatTypeFeignService.selectDataByCondition(Collections.singletonList(
                        new Condition("name", "eq", type, null)));

        if (mdmMatTypeResult.getBody().getCode() == 0) {
            List<LinkedHashMap> data = (List<LinkedHashMap>) mdmMatTypeResult.getBody().getData();
            MdmMatType mdmMatType = JSON.parseObject(JSON.toJSONString(data.stream().findFirst().get()),
                    MdmMatType.class);
            return mdmMatType.getCode();
        } else {
            return null;
        }
    }

}
